"""认证相关的API路由 - 处理用户登录、token验证等功能。"""

import hashlib
import secrets
import time
from datetime import datetime, timedelta
from typing import Optional
from fastapi import APIRouter, HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi.responses import JSONResponse

from .models import (
    LoginRequest, 
    LoginResponse, 
    UserInfo, 
    ValidateTokenRequest, 
    ValidateTokenResponse
)
from utils.logger import logger

# 创建认证路由
auth_router = APIRouter(prefix="/auth", tags=["Authentication"])

# 简单的内存存储（生产环境应使用数据库）
USERS_DB = {
    "admin": {
        "password_hash": "240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9",  # "admin123" 的SHA256
        "userId": "admin_user_001",
        "username": "admin",
        "created_at": "2024-01-01T00:00:00Z"
    },
    "test": {
        "password_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",  # "test" 的SHA256
        "userId": "test_user_001",
        "username": "test",
        "created_at": "2024-01-01T00:00:00Z"
    }
}

# Token存储（生产环境应使用Redis或数据库）
TOKENS_DB = {}

# HTTP Bearer token scheme
security = HTTPBearer()

def hash_password(password: str) -> str:
    """对密码进行SHA256哈希"""
    return hashlib.sha256(password.encode()).hexdigest()

def generate_token() -> str:
    """生成随机token"""
    return secrets.token_urlsafe(32)

def verify_password(password: str, password_hash: str) -> bool:
    """验证密码"""
    return hash_password(password) == password_hash

@auth_router.post("/login", response_model=LoginResponse)
async def login(request: LoginRequest):
    """用户登录接口
    
    Args:
        request: 登录请求，包含用户名和密码
        
    Returns:
        LoginResponse: 登录结果，包含userId和token
    """
    try:
        logger.info(f"用户登录请求: username={request.username}")
        
        # 检查用户是否存在
        if request.username not in USERS_DB:
            logger.warning(f"用户不存在: {request.username}")
            return LoginResponse(
                success=False,
                message="用户名或密码错误"
            )
        
        user = USERS_DB[request.username]
        
        # 验证密码
        if not verify_password(request.password, user["password_hash"]):
            logger.warning(f"密码错误: {request.username}")
            return LoginResponse(
                success=False,
                message="用户名或密码错误"
            )
        
        # 生成token
        token = generate_token()
        
        # 存储token（设置过期时间为24小时）
        TOKENS_DB[token] = {
            "userId": user["userId"],
            "username": user["username"],
            "expires_at": time.time() + 24 * 3600  # 24小时后过期
        }
        
        # 更新最后登录时间
        user["last_login"] = datetime.now().isoformat()
        
        logger.info(f"用户登录成功: {request.username}, userId={user['userId']}")
        
        return LoginResponse(
            success=True,
            message="登录成功",
            userId=user["userId"],
            token=token
        )
        
    except Exception as e:
        logger.error(f"登录过程中发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail="登录失败，请稍后重试")

@auth_router.post("/validate", response_model=ValidateTokenResponse)
async def validate_token(request: ValidateTokenRequest):
    """验证token有效性
    
    Args:
        request: token验证请求
        
    Returns:
        ValidateTokenResponse: 验证结果
    """
    try:
        token = request.token
        
        # 检查token是否存在
        if token not in TOKENS_DB:
            return ValidateTokenResponse(
                valid=False,
                message="Token无效"
            )
        
        token_info = TOKENS_DB[token]
        
        # 检查token是否过期
        if time.time() > token_info["expires_at"]:
            # 删除过期token
            del TOKENS_DB[token]
            return ValidateTokenResponse(
                valid=False,
                message="Token已过期"
            )
        
        return ValidateTokenResponse(
            valid=True,
            userId=token_info["userId"],
            message="Token有效"
        )
        
    except Exception as e:
        logger.error(f"Token验证过程中发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail="Token验证失败")

@auth_router.post("/logout")
async def logout(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """用户登出接口
    
    Args:
        credentials: HTTP Bearer token
        
    Returns:
        登出结果
    """
    try:
        token = credentials.credentials
        
        # 删除token
        if token in TOKENS_DB:
            user_info = TOKENS_DB[token]
            del TOKENS_DB[token]
            logger.info(f"用户登出成功: userId={user_info.get('userId')}")
            return JSONResponse(
                content={"success": True, "message": "登出成功"}
            )
        else:
            return JSONResponse(
                content={"success": False, "message": "Token无效"}
            )
            
    except Exception as e:
        logger.error(f"登出过程中发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail="登出失败")

@auth_router.get("/user", response_model=UserInfo)
async def get_user_info(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """获取当前用户信息
    
    Args:
        credentials: HTTP Bearer token
        
    Returns:
        UserInfo: 用户信息
    """
    try:
        token = credentials.credentials
        
        # 验证token
        if token not in TOKENS_DB:
            raise HTTPException(status_code=401, detail="Token无效")
        
        token_info = TOKENS_DB[token]
        
        # 检查token是否过期
        if time.time() > token_info["expires_at"]:
            del TOKENS_DB[token]
            raise HTTPException(status_code=401, detail="Token已过期")
        
        # 获取用户信息
        username = token_info["username"]
        user = USERS_DB[username]
        
        return UserInfo(
            userId=user["userId"],
            username=user["username"],
            created_at=user["created_at"],
            last_login=user.get("last_login")
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取用户信息过程中发生错误: {str(e)}")
        raise HTTPException(status_code=500, detail="获取用户信息失败")

# 辅助函数：从token获取userId
async def get_current_user_id(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
    """从token获取当前用户ID（依赖注入函数）
    
    Args:
        credentials: HTTP Bearer token
        
    Returns:
        str: 用户ID
    """
    token = credentials.credentials
    
    if token not in TOKENS_DB:
        raise HTTPException(status_code=401, detail="Token无效")
    
    token_info = TOKENS_DB[token]
    
    if time.time() > token_info["expires_at"]:
        del TOKENS_DB[token]
        raise HTTPException(status_code=401, detail="Token已过期")
    
    return token_info["userId"]